package com;

import com.pojo.Role;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class DemoTest {

    public static void main(String[] args) {

    }

    @Test
    public void testRedisAdd() {
        Jedis jedis = new Jedis("localhost", 6379);

        //测试单线程，一秒可以传入多少数据
        int i = 0;
        long startTime = System.currentTimeMillis();
        while (true) {
            long endTime = System.currentTimeMillis();
            if (endTime - startTime > 1000) {
                break;
            } else {
                ++i;
                jedis.set("test_" + i, i + "");
            }
        }
        jedis.close();
        System.out.println("一秒添加数据总数：" + i);
    }

    @Test
    public void testDelRedisData() {
        Jedis jedis = new Jedis("localhost", 6379);
        //测试一秒能删除多少数据
        int i = 0;
        long startTime = System.currentTimeMillis();
        while (true) {
            long endTime = System.currentTimeMillis();
            if (endTime - startTime > 1000) {
                break;
            } else {
                ++i;
                jedis.del("test_" + i);
            }
        }
        jedis.close();
        System.out.println("一秒删除数据总数：" + i);

    }


    @Test
    public void testGetRedisData() {
        Jedis jedis = new Jedis("localhost", 6379);
        //测试一秒能删除多少数据
        int i = 0;
        long startTime = System.currentTimeMillis();
        while (true) {
            long endTime = System.currentTimeMillis();
            if (endTime - startTime > 1000) {
                break;
            } else {
                ++i;
                String s = jedis.get("test_" + i);
            }
        }
        jedis.close();
        System.out.println("一秒获取数据总数：" + i);

    }

    @Test
    public void testRedisConfig() {
        //redis 线程池进行配置
        JedisPoolConfig config = new JedisPoolConfig();
        //最大空闲数
        config.setMaxIdle(50);
        //最大连接数
        config.setMaxTotal(100);
        //最大等待毫秒数
        config.setMaxWaitMillis(20000);
        JedisPool pool = new JedisPool(config, "localhost", 6379);
        Jedis jedis = pool.getResource();
        //如果需要密码
        //jedis.auth("user","password");
    }

    @Test
    public void testStringRedisTemplate() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
        Role role = new Role();
        role.setId(1L);
        role.setRoleName("role_1");
        role.setNote("role_1_note");
        redisTemplate.opsForValue().set("role_1", role);
        //使用的可能不是同一个连接器，如果需要使用同时连接器，可以使用SessionCallback 来实现
        Role r = (Role) redisTemplate.opsForValue().get("role_1");
        System.out.println(r);
    }

    @Test
    public void testStringRedisTemplateSessionCallback() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
        //使用同一个连接器，执行一组操作
        Role role = (Role) redisTemplate.execute(new SessionCallback<Role>() {
            @Override
            public Role execute(RedisOperations redisOperations) throws DataAccessException {
                Role r = new Role();
                r.setId(2L);
                r.setRoleName("role_2");
                r.setNote("role_2_note");
                redisOperations.boundValueOps("role_2").set(r);
                return (Role) redisOperations.boundValueOps("role_2").get();
            }
        });
        System.out.println(role);
    }

    @Test
    public void testString() {
        //练习 RedsTemplate 对字符串的操作
//        set key value
//        get key
//        del key
//        strlen key
//        getset key value       修改原值，并将旧值返回
//        getrange key start end 获取值的子串
//        append key value       将新的字符串 value，加入到原来 key 指向的字符串末，返回 key
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);

        //设置
        redisTemplate.opsForValue().set("k_1", "1111");
        redisTemplate.opsForValue().set("k_2", "2222");

        //获取
        String val1 = (String) redisTemplate.opsForValue().get("k_1");
        String val2 = (String) redisTemplate.opsForValue().get("k_2");
        System.out.println(val1 + "," + val2);

        //删除
        //redisTemplate.delete("k_2");

        //求长度
        Long length = redisTemplate.opsForValue().size("k_1");
        System.out.println(length);

        // 设值新值并返回旧值
        String oldValue2 = (String) redisTemplate.opsForValue().getAndSet(
                "k_1", "new_value2");
        System.out.println(oldValue2);

        // 通过key获取值.
        String value2 = (String) redisTemplate.opsForValue().get("k_1");
        System.out.println(value2);

        // 求子串
        String rangeValue2 = redisTemplate.opsForValue().get("k_1", 0, 3);
        System.out.println(rangeValue2);

        // 追加字符串到末尾，返回新串长度
        int newLen = redisTemplate.opsForValue().append("k_1", "_app");
        System.out.println(newLen);
        String appendValue2 = (String) redisTemplate.opsForValue().get("k_1");
        System.out.println(appendValue2);
    }


    //事务
    @Test
    public void testRedisTransaction(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);

        SessionCallback<String> callback = new SessionCallback<String>() {

            @Override
            public String execute(RedisOperations redisOperations) throws DataAccessException {
                //开启事务
                redisOperations.multi();
                redisOperations.opsForValue().set("kk_1", "bbbb");
                try {
                    Thread.sleep(6000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //执行事务
                redisOperations.exec();
                return (String) redisOperations.boundValueOps("kk_1").get();
            }
        };

        String val = (String) redisTemplate.execute(callback);
        System.out.println("执行后的数据:"+val);
    }
}
